namespace HZY.Framework.Repository.EntityFramework.MateEncrypt;

/// <summary>
/// 密钥加密
/// </summary>
public class EncryptHelper
{
    /// <summary>
    /// 加密
    /// </summary>
    /// <param name="input"></param>
    /// <param name="algorithm"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public static string Encrypt(string input, TableFieldEncryptAlgorithm algorithm, string key = "defaultKey")
    {
        switch (algorithm)
        {
            case TableFieldEncryptAlgorithm.MD5_32:
                return ComputeMd5(input);
            case TableFieldEncryptAlgorithm.MD5_16:
                return ComputeMd5(input).Substring(8, 16);
            case TableFieldEncryptAlgorithm.BASE64:
                return Convert.ToBase64String(Encoding.UTF8.GetBytes(input));
            case TableFieldEncryptAlgorithm.AES:
                return AesEncrypt(input, key);
            case TableFieldEncryptAlgorithm.RSA:
                return RsaEncrypt(input, key);
            case TableFieldEncryptAlgorithm.SM2:
                return Sm2Encrypt(input, key);
            case TableFieldEncryptAlgorithm.SM3:
                return ComputeSm3(input);
            case TableFieldEncryptAlgorithm.SM4:
                return Sm4Encrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithMD5AndDES:
                return PbeWithMD5AndDesEncrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithMD5AndTripleDES:
                return PbeWithMD5AndTripleDesEncrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithHMACSHA512AndAES_256:
                return PbeWithHmacSha512AndAes256Encrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithSHA1AndDESede:
                return PbeWithSha1AndDesEdeEncrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithSHA1AndRC2_40:
                return PbeWithSha1AndRc240Encrypt(input, key);
            default:
                throw new ArgumentException("Unsupported encryption algorithm");
        }
    }

    /// <summary>
    /// 解密
    /// </summary>
    /// <param name="input"></param>
    /// <param name="algorithm"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    /// <exception cref="InvalidOperationException"></exception>
    /// <exception cref="ArgumentException"></exception>
    public static string Decrypt(string input, TableFieldEncryptAlgorithm algorithm, string key = "defaultKey")
    {
        switch (algorithm)
        {
            case TableFieldEncryptAlgorithm.MD5_32:
            case TableFieldEncryptAlgorithm.MD5_16:
                return input;
            case TableFieldEncryptAlgorithm.BASE64:
                return Encoding.UTF8.GetString(Convert.FromBase64String(input));
            case TableFieldEncryptAlgorithm.AES:
                return AesDecrypt(input, key);
            case TableFieldEncryptAlgorithm.RSA:
                return RsaDecrypt(input, key);
            case TableFieldEncryptAlgorithm.SM2:
                return Sm2Decrypt(input, key);
            case TableFieldEncryptAlgorithm.SM3:
                throw new InvalidOperationException("SM3 is a one-way hash function and cannot be decrypted.");
            case TableFieldEncryptAlgorithm.SM4:
                return Sm4Decrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithMD5AndDES:
                return PbeWithMD5AndDesDecrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithMD5AndTripleDES:
                return PbeWithMD5AndTripleDesDecrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithHMACSHA512AndAES_256:
                return PbeWithHmacSha512AndAes256Decrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithSHA1AndDESede:
                return PbeWithSha1AndDesEdeDecrypt(input, key);
            case TableFieldEncryptAlgorithm.PBEWithSHA1AndRC2_40:
                return PbeWithSha1AndRc240Decrypt(input, key);
            default:
                throw new ArgumentException("Unsupported decryption algorithm");
        }
    }

    private static string ComputeMd5(string input)
    {
        using var md5 = MD5.Create();

        var inputBytes = Encoding.UTF8.GetBytes(input);
        var hashBytes = md5.ComputeHash(inputBytes);
        return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
    }

    private static string ComputeSm3(string input)
    {
        // 假设有一个 SM3 的实现

        return "SM3_" + input;
    }

    private static string AesEncrypt(string input, string key)
    {
        // 假设有一个 AES 的实现
        return "AES_" + input;
    }

    private static string AesDecrypt(string input, string key)
    {
        // 假设有一个 AES 的实现
        return input.Replace("AES_", "");
    }

    private static string RsaEncrypt(string input, string key)
    {
        // 假设有一个 RSA 的实现
        return "RSA_" + input;
    }

    private static string RsaDecrypt(string input, string key)
    {
        // 假设有一个 RSA 的实现
        return input.Replace("RSA_", "");
    }

    private static string Sm2Encrypt(string input, string key)
    {
        // 假设有一个 SM2 的实现
        return "SM2_" + input;
    }

    private static string Sm2Decrypt(string input, string key)
    {
        // 假设有一个 SM2 的实现
        return input.Replace("SM2_", "");
    }

    private static string Sm4Encrypt(string input, string key)
    {
        // 假设有一个 SM4 的实现
        return "SM4_" + input;
    }

    private static string Sm4Decrypt(string input, string key)
    {
        // 假设有一个 SM4 的实现
        return input.Replace("SM4_", "");
    }

    private static string PbeWithMD5AndDesEncrypt(string input, string key)
    {
        // 假设有一个 PBEWithMD5AndDES 的实现
        return "PBEWithMD5AndDES_" + input;
    }

    private static string PbeWithMD5AndDesDecrypt(string input, string key)
    {
        // 假设有一个 PBEWithMD5AndDES 的实现
        return input.Replace("PBEWithMD5AndDES_", "");
    }

    private static string PbeWithMD5AndTripleDesEncrypt(string input, string key)
    {
        // 假设有一个 PBEWithMD5AndTripleDES 的实现
        return "PBEWithMD5AndTripleDES_" + input;
    }

    private static string PbeWithMD5AndTripleDesDecrypt(string input, string key)
    {
        // 假设有一个 PBEWithMD5AndTripleDES 的实现
        return input.Replace("PBEWithMD5AndTripleDES_", "");
    }

    private static string PbeWithHmacSha512AndAes256Encrypt(string input, string key)
    {
        // 假设有一个 PBEWithHMACSHA512AndAES_256 的实现
        return "PBEWithHMACSHA512AndAES_256_" + input;
    }

    private static string PbeWithHmacSha512AndAes256Decrypt(string input, string key)
    {
        // 假设有一个 PBEWithHMACSHA512AndAES_256 的实现
        return input.Replace("PBEWithHMACSHA512AndAES_256_", "");
    }

    private static string PbeWithSha1AndDesEdeEncrypt(string input, string key)
    {
        // 假设有一个 PBEWithSHA1AndDESede 的实现
        return "PBEWithSHA1AndDESede_" + input;
    }

    private static string PbeWithSha1AndDesEdeDecrypt(string input, string key)
    {
        // 假设有一个 PBEWithSHA1AndDESede 的实现
        return input.Replace("PBEWithSHA1AndDESede_", "");
    }

    private static string PbeWithSha1AndRc240Encrypt(string input, string key)
    {
        // 假设有一个 PBEWithSHA1AndRC2_40 的实现
        return "PBEWithSHA1AndRC2_40_" + input;
    }

    private static string PbeWithSha1AndRc240Decrypt(string input, string key)
    {
        // 假设有一个 PBEWithSHA1AndRC2_40 的实现
        return input.Replace("PBEWithSHA1AndRC2_40_", "");
    }
}